#ifndef __BASIC_DATETIME_H__
#define __BASIC_DATETIME_H__

#include <basic/misc.h>

__BEGIN_DECLS

#define MIN_DATE        		"19700101"	/* 最小年 */
#define MAX_DATE        		"39991231"	/* 最大年 */
#define MIN_TIME        		"19700101000000"	/* 最小时刻 */
#define MAX_TIME        		"39991231595959"	/* 最大时刻 */
#define DATE_DEFAULT_FMT        "%Y%m%d"    /* 日期缺省格式 */
#define DATE_COMMON_FMT         "%F"        /* 日期普通格式 */
#define TIMESTAMP_DEFAULT_FMT   "%Y%m%d%H%M%S"  /* 时间戳缺省格式 */
#define TIMESTAMP_COMMON_FMT    "%F %T"     /* 时间戳普通格式 */

#define TIMESTAMP_SIZE			14			/* 时间戳大小 */
#define TIMESTAMP_COMMON_SIZE	19			/* 普通时间戳大小 */
#define DATE_SIZE				8			/* 日期大小 */
#define DATE_COMMON_SIZE		10		    /* 普通日期大小 */
#define TIME_SIZE				6			/* 时刻大小 */
#define TIME_COMMON_SIZE		8			/* 普通时刻大小 */

#define SECOND_OF_MINUTE(n)		((n)*60)	/* n分钟秒数 */
#define SECOND_OF_HOUR(n)		((n)*SECOND_OF_MINUTE(60))	/* n小时秒数 */
#define SECOND_OF_DAY(n)		((n)*SECOND_OF_HOUR(24))	/* n天秒数 */

#define IS_LEAP_YEAR(year) \
    (((year)%4==0 && (year)%100!=0) || ((year)%400==0))

/*
 * 月的天数
 */
extern int	/* 天数(正整数):成功 -1:参数无效 */
month_days(
        int yyyy,			/* [IN] 年 */
        int mm				/* [IN] 月 */
        );

/*
 * 当前日期
 */
extern int	/* 天数 */
curr_date(
        char *curr_dt		/* [OUT] 当前日期字串 */
        );

extern char *	/* 当前日期字串，即输出参数curr_dt */
curr_date_str(
        char *curr_dt		/* [OUT] 当前日期字串 */
        );

/*
 * 当前时间戳
 */
extern time_t	/* 秒数 */
curr_timestamp(
        char *curr_ts		/* [OUT] 当前时间戳字串 */
        );

extern char *	/* 当前时间戳字串，即输出参数curr_ts */
curr_timestamp_str(
        char *curr_ts		/* [OUT] 当前时间戳字串 */
        );

/*
 * 两个日期之间相差天数
 */
extern int	/* 0:成功 -1:参数无效 */
diff_date(
        char *begin_date,	/* [IN] 开始日期 */
        char *end_date,		/* [IN] 结束日期 */
        long *diff_days		/* [OUT] 相差天数 */
        );

/*
 * 两个时间戳之间相差秒数
 */
extern int	/* 0:成功 -1:参数无效 */
diff_timestamp(
        char *begin_ts,		/* [IN] 开始时间戳 */
        char *end_ts,		/* [IN] 结束时间戳 */
        long *diff_secs		/* [OUT] 相差秒数 */
        );

/*
 * 计算偏移日期
 */
extern char *	/* 参数result_dt NULL:输入参数错误 */
change_date(
        char *init_date_str,	/* [IN] 起始日期 */
        long days,				/* [IN] 偏移天数 */
        char *result_dt	        /* [OUT] 结果日期
                                   NULL则分配缓冲区，勿忘释放 */
        );

/*
 * 计算偏移时间戳
 */
extern char *	/* 参数result_ts NULL:输入参数错误 */
change_timestamp(
        char *init_ts,		/* [IN] 起始时间戳 */
        long secs,			/* [IN] 偏移秒数 */
        char *result_ts		/* [OUT] 结果时间戳
                               NULL则分配缓冲区，勿忘释放 */
        );

/*
 * 检查日期
 */
extern int	/* 0:成功 -1:日期无效 */
check_date(
        char *date			/* [IN] 日期 */
        );

/*
 * 检查时刻
 */
extern int	/* 0:成功 -1:时刻无效 */
check_time(
        char *time			/* [IN] 时刻 */
        );

/*
 * 检查时间戳
 */
extern int	/* 0:成功 -1:时间戳无效 */
check_timestamp(
        char *ts			/* [IN] 时间戳 */
        );

/*
 * 将时刻转换成格式YYYYMMDDhhmmss的字符串
 */
extern char *   /* 时间戳字符串，即参数ts_str，NULL:错误 */
timestamp_to_str(
        time_t ts,		    /* [IN] 时刻 */
        char *ts_str		/* [OUT] 字符串 */
        );

/*
 * 将格式YYYYMMDDhhmmss的字符串转换成时刻
 */
extern time_t	/* 时刻 */
timestamp_from_str(
        char *ts_str 		/* [IN] 字符串 */
        );

/*
 * 时间戳的年信息
 */
extern int  /* 0:成功 -1:参数无效 */
timestamp_year(
        char *ts_str,       /* [IN] 时间戳字符串 */
        int *year,          /* [OUT] 年份 */
        int *yearday        /* [OUT] 年中天顺序号 */
        );

/*
 * 时间戳的周信息
 */
extern int  /* 0:成功 -1:参数无效 */
timestamp_week(
        char *ts_str,       /* [IN] 时间戳字符串 */
        int *year,          /* [OUT] 年份 */
        int *week,          /* [OUT] 周数 */
        int *weekday        /* [OUT] 周中天顺序号 0-6:周日-周六 */
        );

/*
 * 格式化日期字符串
 */
extern char *   /* 格式化字符串，即参数out_date */
date_fmt(
        char *in_date,      /* [IN] 源日期 */
        char *in_fmt,       /* [IN] 源格式
                               NULL为DATE_DEFAULT_FMT */
        char *out_date,     /* [OUT] 目标日期
                               NULL则分配缓冲区，勿忘释放 */
        char *out_fmt       /* [IN] 目标格式
                               NULL为DATE_COMMON_FMT */
        );

/*
 * 格式化时间戳字符串
 */
extern char *   /* 格式化字符串，即参数out_ts */
timestamp_fmt(
        char *in_ts,        /* [IN] 源时间戳 */
        char *in_fmt,       /* [IN] 源格式
                               NULL为TIMESTAMP_DEFAULT_FMT */
        char *out_ts,       /* [OUT] 目标时间戳
                               NULL则分配缓冲区，勿忘释放 */
        char *out_fmt       /* [IN] 目标格式
                               NULL为TIMESTAMP_COMMON_FMT */
        );

extern int
diff_millisecond(
        struct timeval tv1,
        struct timeval tv2
        );

__END_DECLS

#endif
